
function Promise(exectur) {
    this.PromiseResult = null
    this.PromiseState = 'pendding'
    const _this = this
    this.callbacks = []


    function resolve(data) {
        if (_this.PromiseState !== 'pendding') return
        _this.PromiseResult = data
        _this.PromiseState = 'fulfiled'

        setTimeout(() => {
            _this.callbacks.forEach(item => {
                item.onResolve(data)
            })
        })
    }
    function reject(data) {
        if (_this.PromiseState !== 'pendding') return
        _this.PromiseResult = data
        _this.PromiseState = 'rejected'

        setTimeout(() => {
            _this.callbacks.forEach(item => {
                item.onReject(data)
            })
        })



    }
    try {
        exectur(resolve, reject)
    } catch (error) {
        reject(error)
    }

}
Promise.prototype.then = function (onResolve, onReject) {
    const _this = this
    // value回调为空时 设置默认值进行传递
    if (typeof onResolve !== 'function') {
        onResolve = value => value
    }
    // 异常穿透 设置then的错误回调 默认值
    if (typeof onReject !== 'function') {
        onReject = reason => {
            throw reason
        }
    }
    return new Promise((resolve, reject) => {
        function callback(type) {
            try {
                let result = type(_this.PromiseResult)
                if (result instanceof Promise) {
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })

                } else {
                    resolve(result)
                }
            } catch (error) {
                reject(error)
            }
        }

        if (this.PromiseState === 'fulfiled') {
            setTimeout(() => {
                callback(onResolve)
            })
        }

        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onReject)
            });
        }

        if (this.PromiseState === 'pendding') {
            this.callbacks.push({
                onResolve: function () {
                    callback(onResolve)
                }, onReject: function () {
                    callback(onReject)
                }
            })
        }

    })

}
Promise.prototype.catch = function (onReject) {
    return this.then(undefined, onReject)
}

Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(v => {
                resolve(value)
            }, r => {
                reject(value)
            })
        } else {
            resolve(value)
        }
    })
}
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

Promise.all =function(promises) {
   return new Promise((resolve,reject)=>{
    let count = 0
    let arr = []
        for(let i = 0 ; i < promises.length;i++) {
             promises[i].then(v=>{
                count++
                arr[i] = v
                if(count === promises.length) {
                    resolve(arr)
                }
             },r=>{
                reject(r)
             })
        }
   })
}
Promise.race =function(promises) {
    return new Promise((resolve,reject)=>{
        for(let i = 0 ; i < promises.length;i++) {
           promises[i].then(v=>{
                resolve(v)
           },r=>{
                reject(r)
           })      
        }
    })
 }